package _21_多线程juc._countdownlatch;

import java.util.Random;
import java.util.concurrent.CountDownLatch;

/**
 *
 * 核心参数
 *      count           等待子任务的个数
 * 有两个核心方法
 *      .countDown()    子任务执行完毕后，通知主任务
 *      .await()        主任务在哪等待子任务
 *
 * 应用一：
 *      让 主任务 等待 所有子任务执行完毕后，再继续执行
 * 应用二：
 *      让所有子任务同时执行，打印开始时间
 *
 *      扩展（模拟百米冲刺）
 *          用一个共享 CountDownLatch(1) order 模拟发令枪，
 *          用一个共享 CountDownLatch(n) answer 模拟n个运动员，
 *          多个运动员在开始执行任务前首先 order.await() 集合，等待 order 1=>0 开始执行
 */
public class CountDownLatchTest01 {

    public static void main(String[] args) throws InterruptedException {
        // 定义子任务的个数
        int count = 3;
        // 主任务 latch
        CountDownLatch latch = new CountDownLatch(count);
        // 主任务开始
        System.out.println("主任务开始...");

        Random random = new Random();
        // 三个子任务执行，执行完通知 主任务
        for (int i = 0; i < count; i++) {
            new Thread(() -> {
                // 子线程执行业务，使用随机数模拟执行时间长短
                try {
                    int num = random.nextInt(8);
                    Thread.sleep(num * 1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                // 子任务执行完毕
                System.out.println( "  " + Thread.currentThread().getName() + " 子线程执行任务完毕");
                // 执行完毕通知主任务
                latch.countDown();
            }).start();
        }

        // 主任务等待子任务全部执行完毕
        latch.await();

        // 主任务继续 业务
        System.out.println("全部子任务执行完毕，主任务继续...");
        Thread.sleep(3000);

        // 主任务执行完毕
        System.out.println("主任务执行完毕");
    }

}
